package com.android.calculator

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.text.TextUtils
import android.view.View
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.android.calculator.ui.theme.*
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.tencent.mmkv.MMKV
import java.text.DecimalFormat


class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        NavigationBarStatusBar(this);
        setContent {
            CalculatorTheme {
                Calculator()
            }
        }
    }


    val keyBoardKeys = arrayOf(
        arrayOf("C" to symbolColor, "删除" to symbolColor, "÷" to symbolColor),
        arrayOf("7" to numberColor, "8" to numberColor, "9" to numberColor, "*" to symbolColor),
        arrayOf("4" to numberColor, "5" to numberColor, "6" to numberColor, "-" to symbolColor),
        arrayOf("1" to numberColor, "2" to numberColor, "3" to numberColor, "+" to symbolColor),
        arrayOf("00" to numberColor, "0" to numberColor, "." to numberColor, "=" to symbolColor),
    )


    @OptIn(ExperimentalAnimationApi::class)
    @Composable
    fun Calculator() {
        var state by remember {
            mutableStateOf(CalculatorState())
        }
        var visible by remember {
            mutableStateOf(false)
        }

        var states by remember {
            mutableStateOf(getRecordList())
        }

        Column(modifier = Modifier.fillMaxSize()) {
            Title()
            Box(
                modifier = Modifier
                    .weight(1f)
                    .fillMaxSize()
            ) {
                Column(
                    modifier = Modifier
                        .fillMaxWidth()
                        .wrapContentHeight()
                        .align(Alignment.BottomEnd)
                ) {
                    Text(
                        text = state.number1 + state.opt + state.number2,
                        fontSize = 35.sp,
                        modifier = Modifier
                            .align(Alignment.End)
                            .padding(end = 16.dp)
                    )
                    AnimatedContent(targetState = state.number3,modifier = Modifier
                        .align(Alignment.End)
                        .padding(end = 16.dp)) {targetCount ->
                        Text(
                            text = "$targetCount",
                            fontSize = 25.sp,
                        )
                    }

                    Image(
                        painter = painterResource(id = R.drawable.record),
                        contentDescription = null,
                        modifier = Modifier
                            .wrapContentSize()
                            .padding(16.dp)
                            .clickable {
                                visible = !visible;
                                if (visible){
                                    states = getRecordList();
                                }
                            }
                    )
                }
            }
            Row(
                modifier = Modifier
                    .weight(2f)
                    .fillMaxSize()
                    .background(Brush.linearGradient(listOf(topBGColor, bottomBGColor)))
            )
            {
                AnimatedVisibility(visible = visible) {
                    Column() {
                        Text(
                            text = "历史记录",
                            color = titleTextColor,
                            fontSize = 20.sp,
                            fontWeight = FontWeight.Bold,
                            modifier = Modifier
                                .fillMaxWidth()
                                .padding(top = 30.dp)
                                .wrapContentWidth(align = Alignment.CenterHorizontally)
                        )
                        LazyColumn {
                            itemsIndexed(items = states) { index, state -> //遍历内容和索引
                                if (state.number3 == ""){
                                    Text(
                                        text = if (states.size >1){"清除历史记录"}else{"无历史记录"},
                                        color = if (states.size > 1){titleTextColor}else{
                                            Color.Gray},
                                        fontSize = 16.sp,
                                        modifier = Modifier
                                            .fillMaxWidth()
                                            .padding(top = 16.dp)
                                            .wrapContentWidth(align = Alignment.CenterHorizontally)
                                            .clickable {
                                                if (states.size > 1){
                                                    states = deleteAllRecords()
                                                }
                                            }
                                    )
                                }else{
                                    Text(
                                        text = state.number1 + state.opt + state.number2,
                                        fontSize = 35.sp,
                                        textAlign = TextAlign.End,
                                        modifier = Modifier
                                            .fillMaxWidth()
                                            .padding(end = 16.dp)
                                    )
                                    Text(
                                        text = state.number3,
                                        fontSize = 25.sp,
                                        textAlign = TextAlign.End,
                                        modifier = Modifier
                                            .fillMaxWidth()
                                            .padding(end = 16.dp)
                                    )
                                }
                            }
                        }

                    }
                }

                Column(
                    modifier = Modifier
                        .weight(2f)
                        .fillMaxSize()
                        .background(Brush.linearGradient(listOf(topBGColor, bottomBGColor)))
                ) {
                    keyBoardKeys.forEach {
                        Row(
                            modifier = Modifier
                                .weight(1f)
                        ) {
                            it.forEach {
                                Box(
                                    modifier = Modifier
                                        .weight(if (it.first == "删除") 2f else 1f)
                                        .align(Alignment.CenterVertically)
                                ) {
                                    Text(
                                        text = it.first,
                                        color = it.second,
                                        fontSize = 25.sp,
                                        modifier = Modifier
                                            .fillMaxWidth()
                                            .align(Alignment.Center)
                                            .clickable {
                                                state = calculate(state, it.first)
                                            },
                                        textAlign = TextAlign.Center,
                                    )
                                }
                            }
                        }
                    }
                }
            }

        }
    }

    /**
     * 标题栏
     */
    @Composable
    fun Title() {
        Text(
            text = "计算器",
            color = titleTextColor,
            fontSize = 20.sp,
            fontWeight = FontWeight.Bold,
            modifier = Modifier
                .fillMaxWidth()
                .padding(top = 30.dp)
                .wrapContentWidth(align = Alignment.CenterHorizontally)
        )
    }



    /**
     * 根据点击内容进行计算
     */
    fun calculate(state: CalculatorState, input: String): CalculatorState {
        return when (input) {
            in "0".."9" -> if (TextUtils.isEmpty(state.opt)) {
                state.copy(number1 = state.number1 + input)
            } else if(!TextUtils.isEmpty(state.number3)){
                state.copy(number1 = input, number2 = "", number3 = "", opt = "")
            }else{
                state.copy(number2 = state.number2 + input)
            }
            in arrayOf(
                "+",
                "-",
                "*",
                "÷"
            ) -> if (TextUtils.isEmpty(state.number1) || !TextUtils.isEmpty(state.number3)) {
                state
            } else {
                state.copy(opt = input)
            }
            in "=" -> saveAndCalculate(state)
            in "C" -> state.copy(number1 = "", number2 = "", number3 = "", opt = "")
            in "删除" -> if(!TextUtils.isEmpty(state.number3)){
                state
            }else if (!TextUtils.isEmpty(state.number2)) {
                state.copy(number2 = state.number2.substring(0, state.number2.length - 1))
            } else if (!TextUtils.isEmpty(state.opt)) {
                state.copy(opt = state.opt.substring(0, state.opt.length - 1))
            } else if (!TextUtils.isEmpty(state.number1)) {
                state.copy(number1 = state.number1.substring(0, state.number1.length - 1))
            } else {
                state
            }
            in "." ->  if(!TextUtils.isEmpty(state.number3)){
                state
            }else if (TextUtils.isEmpty(state.opt)) {
                if (state.number1.contains(".")) {
                    state
                } else {
                    state.copy(number1 = state.number1 + input)
                }
            } else {
                if (state.number2.contains(".")) {
                    state
                } else {
                    state.copy(number2 = state.number2 + input)
                }
            }
            else -> state
        }
    }

    /**
     * 计算结果并保存
     */
    fun saveAndCalculate(state: CalculatorState): CalculatorState {
        if (TextUtils.isEmpty(state.number2)) {
            return state
        }
        val format = DecimalFormat("0.############")
        var calculatorState = when (state.opt) {
            "+" -> state.copy(number3 = format.format(state.number1.toDouble() + state.number2.toDouble()))
            "-" -> state.copy(number3 = format.format(state.number1.toDouble() - state.number2.toDouble()))
            "*" -> state.copy(number3 = format.format(state.number1.toDouble() * state.number2.toDouble()))
            "÷" -> state.copy(number3 = format.format(state.number1.toDouble() / state.number2.toDouble()))
            else -> state
        }
        saveSp(calculatorState);
        return calculatorState
    }

    /**
     * 保存历史记录，使用MMKV
     */
    fun saveSp(state: CalculatorState) {
        val kv = MMKV.defaultMMKV()
        var decodeString = kv.decodeString("CalculatorData")
        var states: MutableList<CalculatorState>;
        if (!TextUtils.isEmpty(decodeString)) {
            states = Gson().fromJson(
                decodeString,
                object : TypeToken<List<CalculatorState>>() {}.getType()
            )
        } else {
            states = ArrayList<CalculatorState>();
        }
        states.add(state)
        kv.encode("CalculatorData", Gson().toJson(states))
    }

    private fun deleteAllRecords(): List<CalculatorState> {
        val kv = MMKV.defaultMMKV()
        var decodeString = kv.encode("CalculatorData", "")
        return ArrayList<CalculatorState>();
    }

    fun getRecordList(): List<CalculatorState> {
        val kv = MMKV.defaultMMKV()
        var decodeString = kv.decodeString("CalculatorData")
        var states: MutableList<CalculatorState>;
        if (!TextUtils.isEmpty(decodeString)) {
            states = Gson().fromJson(
                decodeString,
                object : TypeToken<List<CalculatorState>>() {}.getType()
            )
        } else {
            states = ArrayList<CalculatorState>();
        }
        states.reverse();
        states.add(CalculatorState())
        return states;
    }


    @Preview(showBackground = true, showSystemUi = true)
    @Composable
    fun DefaultPreview() {
        CalculatorTheme {
            Calculator();
        }
    }

    //隐藏导航栏，状态栏
    private fun NavigationBarStatusBar(activity: Activity) {
        val decorView = activity.window.decorView
        decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                or View.SYSTEM_UI_FLAG_FULLSCREEN
                or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
    }

}

data class CalculatorState(
    var number1: String = "",
    var number2: String = "",
    var number3: String = "",
    var opt: String = ""
);